package Tabla_Simbolos;


import java.util.*;


public class Metodo {
	private String nombre;
	private LinkedList <Atributo> argForm;
	private Tipo tipo;
	private boolean definido;
	private int offset;	
	
 	public Metodo (String ID, Tipo t) {//constructor del Metodo
		nombre = ID;
		argForm = new LinkedList<Atributo>();
		tipo = t;
	}
	
	public Tipo getTipo(){
		return tipo;
	}
	
	public void agregarAtributo(Atributo A){ //agregamos el atributo A, a la lista de atributos
		argForm.add(A);
	}

	public boolean existeAtributo(Atributo A){ 
		int ind = 0;
		boolean Encontre = false;
		while ((ind < argForm.size()) && (Encontre == false)){
			if (argForm.get(ind).getNombre().equals(A.getNombre())){
				Encontre = true;
			}else{
				ind++;
			}
		}
		return Encontre;
	}
	
	public int posicionAtributo(Atributo A){ //devuelve la posicion donde se encuentra el atributo A
		return argForm.indexOf(A);
	}
	
	public boolean mismoTipo(Tipo t){ // verifica si el tipo actual es del mismo tipo que el que pasa como parametro
		return tipo.tipoToString().equals(t.tipoToString());
	}
	
	public Atributo getAtributo(int pos){// retorna el atributo que esta e la posicion pos
		return argForm.get(pos);
	}
	
	public Atributo obtenerAtributo(String Nombre){ // dado un nombre devuelve el atributo asociado, siempre existe, dado que antes de la llamada se verifica esto
		int i = 0;
		while (i< argForm.size()){
			if (argForm.get(i).getNombre().equals(Nombre)){
				return argForm.get(i);	
			}
			i++;
		}				
		return null;
	}
	
	public String getNombre(){
		return nombre;
	}

	public void setDefinido(){ // setea Definido en true, para que de esta forma se sepa si el metodo ya fui leido en la parte del class y no haya repetidos
		definido = true;
	}
	
	public boolean getDefinido(){
		return definido;
	}
	
	public LinkedList<Atributo> getTableArg(){ // retorna la lista de atributos
		return argForm;
	}
	
	public int getOffset(){ // retorna el offset del metodo
		return offset;
	}
	
	public void setOffset(TClase clase){
		if (clase.getNombre().equals(nombre)){
			offset = 0;
		}else{
			offset = 0;
			if (clase.existeMetodoEnPadre(nombre)){
				boolean encontre = false;
				while ((offset==0) && (!encontre)){
					TClase padre = clase.getPadre();
					int index = 0;
					while ((index<padre.getListaMetodos().size()) && (! encontre)){
						if (padre.getListaMetodos().get(index).equals(nombre)){
							offset = index+1;
							encontre = true;
						}else index++;
					}
				}
			}else{
				int offsetPadres = 0;
				TClase clasePadre = clase.getPadre();
				LinkedList<String> listAux = new LinkedList<String>();
				while (!(clasePadre.getNombre().equals("Object"))){
					int index = 0;
					while (index<clasePadre.getListaMetodos().size()){
						if (!(listAux.contains(clasePadre.getListaMetodos().get(index)))){
							offsetPadres++;
							listAux.add(clasePadre.getListaMetodos().get(index));
						}
						index++;
					}
					clasePadre = clasePadre.getPadre();
				}
				int index = 0;
				while ((index<clase.getListaMetodos().size()) && (!(clase.getListaMetodos().get(index).equals(nombre)))){
					index++;
				}
				offset = index + offsetPadres+1;
			}
		}
	}

	public int getCantParametros(){ //retorna cantidad de parametros formales del metodo
		return argForm.size();
	}
}


